package org.cnc.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Polygon;

import javax.swing.JPanel;
import javax.swing.JSplitPane;

import org.cnc.core.DetailModel;
import org.cnc.core.DetailModel.ModelState;


public class ModelDrawer extends JPanel{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private DetailModel model;
	private ModelTop modelTop;
	private ModelLeft modelLeft;
	private ModelFront modelFront;
	
	private Color colorCut = new Color( 180, 60, 60, 120 );
	private Color colorDetail = new Color( 120,120,120, 10);
	private Color colorEmpty = Color.LIGHT_GRAY;
	private Color colorCutted = new Color( 180, 180, 60, 120 );
	private Color colorCutter = Color.BLUE;
	
	private int xPos;
	private int yPos;
	private int zPos;
	
	public ModelDrawer() {
		
		setLayout(new BorderLayout(0, 0));
		JSplitPane splitPane = new JSplitPane();
		//splitPane.setBackground( Color.DARK_GRAY );
		splitPane.setResizeWeight(0.5);
		splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
		add(splitPane, BorderLayout.CENTER);
		
		modelTop = new ModelTop();
		modelTop.setSize(600,600);
		modelTop.setTitle( "Вид сверху" );
		modelLeft = new ModelLeft();
		modelLeft.setSize(600,600);
		modelLeft.setTitle( "Вид спереди" );
		modelFront = new ModelFront();
		modelFront.setSize(600,600);
		modelFront.setTitle( "Вид слева" );
		
		JSplitPane frontAndLeft = new JSplitPane();
		frontAndLeft.setResizeWeight(0.5);
		frontAndLeft.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
		frontAndLeft.setRightComponent(modelFront);
		//frontAndLeft.setBackground( Color.DARK_GRAY );
		frontAndLeft.setLeftComponent(modelLeft);
		
		splitPane.setRightComponent(modelTop);
		splitPane.setLeftComponent(frontAndLeft);
	}
	
	private void updateView ()
	{
		modelTop.updateView();
		modelLeft.updateView();
		modelFront.updateView();
	}
	
	private void updateModel( DetailModel m )
	{
		this.model = m;
	}
	
	private void moveCutter ( int x, int y, int z )
	{
		xPos = x;
		yPos = y;
		zPos = z;
	}
	
	public void update( DetailModel model, int x, int y, int z)
	{
		updateModel( model );
		
		moveCutter(x,y,z);
		
		updateView();
	}
	
	@SuppressWarnings("serial")
	class ModelTop extends ModelView{
		
		@Override
		protected void drawCutter ( Graphics g, int gridSize )
		{	
			g.setColor(colorCutter);
			

			Polygon top = new Polygon();
			
			top.addPoint(xPos*gridSize, ( zPos +1 )*gridSize);
			top.addPoint(xPos*gridSize, ( zPos +1 )*gridSize - gridSize);
			top.addPoint(xPos*gridSize + gridSize, ( zPos +1 )*gridSize - gridSize/2);

			g.fillPolygon( top );
		}
		
		@Override
		protected void drawModel( Graphics g )
	    {
	    	if ( model != null )
	    	{
		    	int gridSize = getHeight()/model.getModelSize(); // 10px

		    	int x0 = 0;
		    	int y0 = 0;
		    	
		    	for ( int y = 0; y < model.getDetailSize(); y++ )
		    	{
		    		for ( int x = 0; x <  model.getModelSize(); x++ )
		    		{
		    			for ( int z = 0; z < model.getModelSize(); z++ )
		    			{
		    				if ( model.detailModel[x][y][z] == ModelState.EMPTY)
		    				{
		    					g.setColor(colorEmpty);
		    					g.drawRect(x0 + x*gridSize, y0 + z*gridSize, gridSize, gridSize);
		    				}
		    				else if ( model.detailModel[x][y][z] == ModelState.DETAIL)
		    				{
		    					g.setColor(colorDetail);
		    					g.fillRect(x0 + x*gridSize, y0 + z*gridSize, gridSize, gridSize);
		    				}
		    				else if ( model.detailModel[x][y][z] == ModelState.CUTTER)
		    				{
		    					g.setColor(colorCut);
		    					g.drawRect(x0 + x*gridSize, y0 + z*gridSize, gridSize, gridSize);
		    					g.fillRect(x0 + x*gridSize, y0 + z*gridSize, gridSize, gridSize);
		    				}
		    				else if ( model.detailModel[x][y][z] == ModelState.CUTTED)
		    				{
		    					g.setColor(colorCutted);
		    					g.drawRect(x0 + x*gridSize, y0 + z*gridSize, gridSize, gridSize);
		    					g.fillRect(x0 + x*gridSize, y0 + z*gridSize, gridSize, gridSize);
		    				}
		    			}
		    			
		    		}
		    	}
		    	
		    	drawCutter( g, gridSize );
	    	}
	    }
	}
	
	@SuppressWarnings("serial")
	class ModelLeft extends ModelView {
		
		@Override
		protected void drawCutter ( Graphics g, int gridSize )
		{	
			g.setColor(colorCutter);
			

			Polygon left = new Polygon();
			
			left.addPoint(xPos*gridSize, yPos*gridSize - 2*gridSize);
			left.addPoint(xPos*gridSize, yPos*gridSize + gridSize );
			left.addPoint(xPos*gridSize + gridSize, yPos*gridSize );
			left.addPoint(xPos*gridSize + gridSize, yPos*gridSize - 2*gridSize);
			
			g.fillPolygon( left );
		}
		
		@Override
		protected void drawModel( Graphics g )
	    {
	    	if ( model != null )
	    	{
		    	int gridSize = getHeight()/model.getModelSize(); // 10px

		    	int x0 = 0;
		    	int y0 = 0;
		    	
		    	// view from center
		    	int z1 = (model.getModelSize() - model.getDetailSize())/2;
		    	int z2 = model.getModelSize() - z1;
		    	
		    	// view from center
		    	for ( int z = z2 - 1; z >= z1; z --)
		    	{
		    		for ( int x = 0; x <  model.getModelSize(); x++ )
		    		{
		    			for ( int y = 0; y < model.getModelSize(); y++ )
		    			{
		    				if ( model.detailModel[x][y][z] == ModelState.EMPTY)
		    				{
		    					g.setColor(colorEmpty);
		    					g.drawRect(x0 + x*gridSize, y0 + (model.getModelSize() - y)*gridSize, gridSize, gridSize);
		    				}
		    				else if ( model.detailModel[x][y][z] == ModelState.DETAIL)
		    				{
		    					g.setColor(colorDetail);
		    					g.fillRect(x0 + x*gridSize, y0 + (model.getModelSize() - y)*gridSize, gridSize, gridSize);
		    				}
		    				else if ( model.detailModel[x][y][z] == ModelState.CUTTER)
		    				{
		    					g.setColor(colorCut);
		    					g.fillRect(x0 + x*gridSize, y0 + (model.getModelSize() - y)*gridSize, gridSize, gridSize);
		    				}
		    				else if ( model.detailModel[x][y][z] == ModelState.CUTTED)
		    				{
		    					g.setColor(colorCutted);
		    					g.fillRect(x0 + x*gridSize, y0 + (model.getModelSize() - y)*gridSize, gridSize, gridSize);
		    				}
		    			}
		    			
		    		}
		    	}
		    	
		    	drawCutter( g, gridSize );
	    	}
	    }
	}
	
	@SuppressWarnings("serial")
	class ModelFront extends ModelView{
		
		@Override
		protected void drawCutter ( Graphics g, int gridSize )
		{	
			g.setColor(colorCutter);
			
			Polygon front = new Polygon();

			front.addPoint(zPos*gridSize, yPos*gridSize - 2*gridSize);
			front.addPoint(zPos*gridSize, yPos*gridSize );
			front.addPoint(zPos*gridSize + gridSize/2, yPos*gridSize + gridSize );
			front.addPoint(zPos*gridSize + gridSize, yPos*gridSize );
			front.addPoint(zPos*gridSize + gridSize, yPos*gridSize - 2*gridSize );
			
			g.fillPolygon( front );
		}
		
		@Override
		protected void drawModel( Graphics g )
	    {
	    	if ( model != null )
	    	{
		    	int gridSize = getHeight()/model.getModelSize(); // 10px

		    	int x0 = 0;
		    	int y0 = 0;
		    	
		    	int x1 = (model.getModelSize() - model.getDetailSize())/2;
		    	int x2 = model.getModelSize() - x1;
		    	
		    	// view from center
		    	for ( int x = x2 - 1; x >= x1; x --)
		    	{
		    		for ( int z = 0; z <  model.getModelSize(); z++ )
		    		{
		    			for ( int y = 0; y < model.getModelSize(); y++ )
		    			{
		    				if ( model.detailModel[x][y][z] == ModelState.EMPTY)
		    				{
		    					g.setColor(colorEmpty);
		    					g.drawRect(x0 + z*gridSize, y0 + (model.getModelSize() - y)*gridSize, gridSize, gridSize);
		    				}
		    				else if ( model.detailModel[x][y][z] == ModelState.DETAIL)
		    				{
		    					g.setColor(colorDetail);
		    					g.fillRect(x0 + z*gridSize, y0 + (model.getModelSize() - y)*gridSize, gridSize, gridSize);
		    				}
		    				else if ( model.detailModel[x][y][z] == ModelState.CUTTER)
		    				{
		    					g.setColor(colorCut);
		    					g.fillRect(x0 + z*gridSize, y0 + (model.getModelSize() - y)*gridSize, gridSize, gridSize);
		    				}
		    				else if ( model.detailModel[x][y][z] == ModelState.CUTTED)
		    				{
		    					g.setColor(colorCutted);
		    					g.fillRect(x0 + z*gridSize, y0 + (model.getModelSize() - y)*gridSize, gridSize, gridSize);
		    				}
		    			}
		    			
		    		}
		    	}
		    	
		    	drawCutter( g, gridSize );
	    	}
	    }
	}
}
